package com.example.victory.service;

import com.example.victory.config.ServiceError;
import com.example.victory.entity.companyEntity.WinnersListEntity;
import com.example.victory.mapper.CustomerMapper;
import com.example.victory.mysql.CustomerMysqlMapper;
import com.example.victory.swagger.handler.WinnersListApiDelegate;
import com.example.victory.swagger.model.*;
import com.example.victory.swagger.model.ApiResponseNull;
import com.cgws.fintech.sdk.api.inner.message.model.ApiRequestRoom;
import com.cgws.fintech.sdk.api.inner.message.model.ApiRequestSendMessage;
import com.cgws.fintech.sdk.api.inner.message.model.InfoRequest;
import com.cgws.fintech.sdk.api.inner.security.model.*;
import com.cgws.fintech.sdk.api.mvp.model.ApiRequestEmployeeQuery;
import com.cgws.fintech.sdk.api.mvp.model.ApiResponseEmployeeQuery;
import com.cgws.fintech.sdk.api.mvp.model.ApiResponseEmployeeQueryData;
import com.cgws.fintech.sdk.api.mvp.model.SysAccount;
import com.cgws.fintech.sdk.common.enums.ImMsgTypeEnum;
import com.cgws.fintech.sdk.common.enums.ImSendUserIdEnum;
import com.cgws.fintech.sdk.common.exception.GlobalException;
import com.cgws.fintech.sdk.common.utils.DateHelper;
import com.example.victory.common.web.ServiceHelper;
import com.cgws.fintech.sdk.inner.utils.web.SessionService;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
@Slf4j
public class WinnersListService implements WinnersListApiDelegate {

    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private CustomerMysqlMapper customerMysqlMapper;
    @Autowired
    private SessionService sessionService;
    @Autowired
    private SendMessageService sendMessageService;
    @Autowired
    private InnerService innerService;
    @Autowired
    private MvpLoginService mvpLoginService;

    // 刷新tag线程数
    @Value("${app.thread.poolsize:10}")
    private Integer threadPoolsize;
    @Value("${app.head.photo.url: https://yfw.cgws.com/emp/api/v1/platform/apps/STAFF/profiles/{}/avatar?width=50&height=20 }")
    private String headPhotoUrl;
    @Value("${winners.list.queryScope}")
    private String queryScope;
    @Value("${winners.list.rankingType}")
    private String rankingType;
    @Value("${app.is.crm.product:true}")
    private boolean isCrmProduct;

    private static ExecutorService executorService;

    @PostConstruct
    private void init() {
        executorService = Executors.newFixedThreadPool(this.threadPoolsize);
    }

    @Override
    public ResponseEntity<ApiResponseQueryCondition> getQueryCondition() {

        ApiResponseQueryConditionData data = new ApiResponseQueryConditionData();
        data.setQueryScope(getKeyValue(queryScope));
        data.setRankingType(getKeyValue(rankingType));

        List<KeyValueDetail> keyValueDetailList = Lists.newArrayList();
        KeyValueDetail keyValueDetail = new KeyValueDetail();
        String lastMonths = getLastMonths(1);
        keyValueDetail.setName(lastMonths.replace("-",""));
        keyValueDetail.setValue(lastMonths.replace("-", "."));
        KeyValueDetail keyValueDetail2 = new KeyValueDetail();
        String lastTwoMonths = getLastMonths(2);
        keyValueDetail2.setName(lastTwoMonths.replace("-",""));
        keyValueDetail2.setValue(lastTwoMonths.replace("-", "."));
        keyValueDetailList.add(keyValueDetail);
        keyValueDetailList.add(keyValueDetail2);

        data.setQueryDate(keyValueDetailList);

        return ResponseEntity.ok(new ApiResponseQueryCondition().data(data));
    }

    /**
     * 获取上i个月
     * @param i 上几个月
     * @return 上几个月字符串
     */
    private String getLastMonths(int i) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.MONTH, -i);
        Date m = c.getTime();
        return sdf.format(m);
    }

    private List<KeyValueDetail> getKeyValue(String Str) {
        List<KeyValueDetail> keyValueDetailList = Lists.newArrayList();
        for (String kv: Str.split(",")) {
            String[] split = kv.split("&");
            KeyValueDetail keyValueDetail = new KeyValueDetail();
            keyValueDetail.setName(split[0]);
            keyValueDetail.setValue(split[1]);
            keyValueDetailList.add(keyValueDetail);
        }
        return keyValueDetailList;
    }

    @Override
    public ResponseEntity<ApiResponseNull> clickLike(ApiRequestClickLike param) {
        ApiRequestClickLikeData data = param.getData();
        ServiceHelper.checkDataNotNull(data, "data");
        ApiRequestClickLikeData.RankingTypeEnum rankingType = data.getRankingType();
        ServiceHelper.checkDataNotNull(rankingType, "data.rankingType");
        String date = data.getDate();
        ServiceHelper.checkDataNotNull(date, "data.date");
        Integer clickRyid = data.getClickRyid();
        ServiceHelper.checkDataNotNull(clickRyid, "data.clickRyid");

        Integer clickLikeType = getRankingTypeValue(rankingType.toString());

        // 获取当前用户
        UserSession userSession = sessionService.getCurrentUserSession(true);
        String imFcid = userSession.getSession().getImFcid();
        String trueName = userSession.getUser().getTrueName();
        String crmId = userSession.getUser().getCrmId();

//        String crmId = "1078184";
//        if (crmId == null) crmId = "1078184";
        Integer ryid = Integer.valueOf(crmId);

        String clickDate = DateHelper.getDateYYYYMMDD(new Date());
        try {
            customerMysqlMapper.insertClickLikeRecord(ryid, clickRyid, date, clickLikeType, clickDate);
        } catch (DuplicateKeyException e) {
            log.error("主键冲突，重复点赞了" + e);
            return ResponseEntity.ok(new ApiResponseNull());
        }

        if (!Objects.equals(clickRyid, ryid)) { // 自己给自己点赞不发送消息
            // 向被点赞人发送消息
            executorService.execute(() -> {
                log.info("异步去推送点赞通知消息...");
                try {
                    sendMessageService.sendMessage(getApiRequestSendMessage(ImSendUserIdEnum.WINNERS_LIST.getCode(),
                            trueName, clickRyid.toString(), imFcid));
                }catch (Exception e){
                    log.error("IM异常,e={}",e);
                }
            });
        }

        return ResponseEntity.ok(new ApiResponseNull());
    }

    /**
     * 远程获取fcid
     * @param crmId  crmId
     * @return   fcid
     */
    private String getRemoteFcid(String crmId) {
        String fcid = null;
        ApiRequestAccount apiRequestAccount=new ApiRequestAccount();
        ApiRequestAccountData apiRequestAccountData=new ApiRequestAccountData();
        apiRequestAccountData.setAccount(crmId);
        apiRequestAccount.setData(apiRequestAccountData);
        ResponseEntity<ApiResponseFcid>  fcidByAccountInner= innerService.getFcidByAccountInner(apiRequestAccount);
        log.info("响应参数:{}",fcidByAccountInner);
        if(fcidByAccountInner.getStatusCode()!= HttpStatus.OK){
            throw new GlobalException(ServiceError.QUERY_FCID_ATTEND_INFO);
        }
        if(fcidByAccountInner.getBody() != null && fcidByAccountInner.getBody().getData() != null &&
                !StringUtils.isEmpty(fcidByAccountInner.getBody().getData().getFcid())){
            fcid = fcidByAccountInner.getBody().getData().getFcid();
        }
        return fcid;
    }

    /**
     * 远程从mvp获取fcid
     * @param crmSysId  crmSysId
     * @return   fcid
     */
    private String getRemoteFcidFromMvp(String crmSysId, String oaSysId) {
        List<SysAccount> sysAccountList = Lists.newArrayList();
        SysAccount sysAccount = new SysAccount();
        sysAccount.setStaffId(crmSysId);
        sysAccount.setSysId("2");
        sysAccountList.add(sysAccount);

        if (oaSysId != null) {
            SysAccount oASysAccount = new SysAccount();
            oASysAccount.setStaffId(oaSysId);
            oASysAccount.setSysId("1");
            sysAccountList.add(oASysAccount);
        }
        ApiRequestEmployeeQuery request = new ApiRequestEmployeeQuery();
        request.setData(sysAccountList);
        ResponseEntity<ApiResponseEmployeeQuery> response = mvpLoginService.queryStaffs(request);
        if (response.getStatusCode() != HttpStatus.OK || response.getBody() == null) {
            throw new GlobalException(ServiceError.MVP_QUERY_FAIL);
        }
        ApiResponseEmployeeQueryData data = response.getBody().getData();
        if (data != null && data.getList() != null && !data.getList().isEmpty()) {
            Map<String, String> fcidAccountMap = new HashMap<>();
            data.getList().forEach( sa -> {
                if (Objects.equals(sa.getState(), 10000)) {
                    fcidAccountMap.put(sa.getSysId(), sa.getFcid());
                }
            });
            if (fcidAccountMap.size() == 1) {
                if (fcidAccountMap.get("2") != null) return fcidAccountMap.get("2");
                else return fcidAccountMap.get("1");
            } else if (fcidAccountMap.size() == 2) {
                return fcidAccountMap.get("2");
            }
        }
        return null;
    }

    private ApiRequestSendMessage getApiRequestSendMessage(String sendUser, String trueName, String clickRyid, String imFcid) {
        //获取fcid
        String fcid = getRemoteFcid(clickRyid);
        String fcidFromMvp = getRemoteFcidFromMvp(clickRyid, getOaAccount(clickRyid));
        String icon = getHeadPhotoUrl(headPhotoUrl, imFcid);

        String content = trueName + "刚刚赞了你";
        ApiRequestSendMessage apiRequestSendMessage = new ApiRequestSendMessage();
//        apiRequestSendMessage.setReveiveUserIdList(Collections.singletonList("15998585558"));
        apiRequestSendMessage.setReveiveUserIdList(Collections.singletonList(fcidFromMvp != null ? fcidFromMvp:fcid));
        apiRequestSendMessage.setSendUserId(sendUser);
        ApiRequestRoom apiRequestRoom = new ApiRequestRoom();
        apiRequestRoom.setBody(content);
        InfoRequest infoRequest = new InfoRequest();

        infoRequest.setIcon(icon);
        infoRequest.setJumpUrl("{\"type\":\"native\",\"nativeBean\":{\"identity\":\"winnersList\"}}");
        infoRequest.setContent(content);
        apiRequestRoom.setInfo(infoRequest);
        apiRequestRoom.setMsgtype(ImMsgTypeEnum.IM_CGWS_WINNERSLISTLIKE.getCode());
        apiRequestSendMessage.setMessageBody(apiRequestRoom);

        return apiRequestSendMessage;
    }

    /**
     * 转换排名类型
     * @param rankingType   排名类型
     * @return  排名类型对应的值
     */
    private Integer getRankingTypeValue (String rankingType) {
        Integer clickLikeType = null;
        switch (rankingType) {
            case "MONTHLY_SQLES":
                clickLikeType = 1;
                break;
            case "ANNUAL_SALES":
                clickLikeType = 2;
                break;
            case "ADD_VALID_ACCOUNTS":
                clickLikeType = 3;
                break;
            case "NEW_ADD_ASSETS":
                clickLikeType = 4;
                break;
            default:
                break;
        }
        return clickLikeType;
    }

    @Override
    public ResponseEntity<ApiResponseWinnersList> getWinnersList(ApiRequestWinnersList param) {
        ApiRequestWinnersListData data = param.getData();
        ServiceHelper.checkDataNotNull(data, "data");
        ApiRequestWinnersListData.QueryScopeEnum queryScope = data.getQueryScope();
        ServiceHelper.checkDataNotNull(queryScope, "data.queryScope");
        ApiRequestWinnersListData.RankingTypeEnum rankingType = data.getRankingType();
        ServiceHelper.checkDataNotNull(rankingType, "data.rankingType");
        String month = data.getDate();
        ServiceHelper.checkDataNotNull(month, "data.date");
        String clickMonth = month;

        // crm 测试环境里只有201901有数据
        if (!isCrmProduct) {
            month = "201901";
        }

        Winners winners = new Winners();
        ApiResponseWinnersList response = new ApiResponseWinnersList();

        // 获取当前用户
        User user = sessionService.getCurrentUserSession(true).getUser();
        String crmId = user.getCrmId();
        if (StringUtils.isEmpty(crmId)) {
            response.setData(winners);
            return ResponseEntity.ok(response);
        }

//        crmId = "1001468";
        List<WinnersListEntity> oneselfEntities = customerMapper.getWinnerList(crmId, queryScope, rankingType, month, true);
        List<WinnersListEntity> winnersListEntities = customerMapper.getWinnerList(crmId, queryScope, rankingType, month, false);

        WinnersList oneself = null;
        Integer clickLikeType = getRankingTypeValue(rankingType.toString());

        Integer ryid = Integer.valueOf(crmId);
        // 获取点赞相关的数据
        if (oneselfEntities != null && oneselfEntities.size() > 0) {
            oneself = oneselfEntities.get(0).toWinnersList();
            getLikeNum(oneself, clickMonth, clickLikeType,ryid);
            formatThousandSeparator(oneself, clickLikeType);
        }

        List<WinnersList> winnersLists = new ArrayList<>();
        winnersListEntities.forEach(entity -> {
            WinnersList winner = entity.toWinnersList();
//            oneself.setReportCard(oneself.getReportCard().trim());
            // 设置点赞相关的数据
            getLikeNum(winner, clickMonth, clickLikeType, ryid);
            formatThousandSeparator(winner, clickLikeType);
            winnersLists.add(winner);
        });

        winners.setOneself(oneself);
        winners.setItems(winnersLists);
        response.setData(winners);

        return ResponseEntity.ok(response);
    }

    /**
     * 格式化千分位
     * @param winner
     * @param clickLikeType
     */
    private void formatThousandSeparator(WinnersList winner, Integer clickLikeType) {
        if (clickLikeType != 3) {
            DecimalFormat decimalFormat = new DecimalFormat(",###");
            winner.setReportCard(decimalFormat.format(new BigDecimal(winner.getReportCard())));
        }
    }

    /**
     *  获取是否被点赞，以及点赞数量, 设置头像url
     * @param winner    风云榜对象
     * @param month
     * @param clickLikeType
     */
    private void getLikeNum(WinnersList winner, String month, Integer clickLikeType, Integer ryid) {
        String accountReal = winner.getRyid().toString();
        String fcidFromMvp = getRemoteFcidFromMvp(accountReal, getOaAccount(accountReal));
        winner.setHeadPhoto(getHeadPhotoUrl(headPhotoUrl, fcidFromMvp != null? fcidFromMvp:getRemoteFcid(accountReal)));
        List<Integer> clickLikes = customerMysqlMapper.getClickLikeCount(winner.getRyid(), month, clickLikeType);
        winner.isClick(clickLikes.contains(ryid));
        winner.setLikeNum(clickLikes.size());
    }

    /**
     * 根据crmId获取oaId
     * @param accountReal accountReal
     * @return oaId
     */
    private String getOaAccount(String accountReal) {
        ApiRequestAccountRealData apiRequestAccountRealData = new ApiRequestAccountRealData();
        apiRequestAccountRealData.setAccountReal(accountReal);
        ApiRequestAccountReal apiRequestAccountReal = new ApiRequestAccountReal();
        apiRequestAccountReal.setData(apiRequestAccountRealData);

        ResponseEntity<ApiResponseGetOaAccountByAccountReal> response = innerService.getOaAccountByAccountReal(apiRequestAccountReal);
        if (response.getStatusCode() != HttpStatus.OK || response.getBody() == null) {
            throw new GlobalException(ServiceError.OA_ACCOUNT_QUERY_FAIL);
        }
        return response.getBody().getData().getOaSysId();
    }

    // 拼接头像url
    private String getHeadPhotoUrl(String baseUrl, String fcid) {
        if (baseUrl != null && fcid != null) {
            return baseUrl.replace("{}", fcid);
        }
        return null;
    }
}
